from rest_framework.generics import GenericAPIView

from iot.models import Cabinet, Point, Warn
from iot_api.base import ret_res
from datetime import datetime, timedelta

from iot_api.serializers import PointSerializer


# 返回指定deptid的全部的点位数据
class MyRoomDetailView(GenericAPIView):
    queryset = Cabinet.objects.all()
    permission_classes = []
    filter_backends = []

    def get(self, request, *args, **kwargs):
        # 获取筛选后的柜子查询集
        queryset = self.filter_queryset(self.get_queryset())

        # 获取请求参数中的部门ID（deptId）
        dept_id = request.query_params.get('deptId')

        # 从 Point 表中查询所有数据
        points = Point.objects.filter(dept_belong_id=dept_id).order_by('create_datetime')

        # 初始化返回数据
        data1 = []

        # 如果指定了部门ID，则筛选出该部门的柜子
        if dept_id:
            cabinets = queryset.filter(dept__id=dept_id).order_by('create_datetime')
            cabinet_dict_map = {}  # 使用字典来存储每个柜子的信息，避免重复
            point1 = Point.objects.filter(dept_belong_id=dept_id).first()
            # 强制转换为字符串  然后变为时间格式
            dt_object = datetime.fromisoformat(str(point1.update_datetime))
            # 指定时间格式
            formatted_time_str = dt_object.strftime("%Y-%m-%d %H:%M:%S")
            for cabinet in cabinets:
                cabinet_dict = {
                    'cabinetName': cabinet.name,
                    'cabinetId': cabinet.id,
                    'warn_value': cabinet.warm_warning,  # 注意字段名可能是 warm_warning 而不是 warm_warning（检查你的模型定义）
                    'early_warn_value': cabinet.warm_early_warning,  # 同上
                    'status': '正常',  # 默认状态为“正常”
                    'update_time': formatted_time_str,
                    'points': [],  # 初始化该柜子的点列表

                }
                cabinet_dict_map[cabinet.id] = cabinet_dict  # 将柜子信息存储到字典中，以柜子ID为键

            # 遍历点，并将它们添加到对应柜子的点列表中
            for point in points:
                cabinet_dict = cabinet_dict_map.get(point.cabinet_id)
                if cabinet_dict:
                    # 添加点信息到柜子字典中
                    cabinet_dict['points'].append({
                        "deptId": point.dept_belong_id,
                        "name": point.name,
                        "code": point.code,
                        "value": point.value,
                        "cabinet_id": point.cabinet_id,
                        "is_warning": point.is_warning,
                    })

                    # 根据is_warning的值更新柜子状态
                    if point.is_warning == 1:  # 报警
                        cabinet_dict['status'] = '报警'
                    elif point.is_warning == 0:  # 预警
                        # 如果柜子状态已经是报警，则不改变，否则设置为预警
                        if cabinet_dict['status'] != '报警':
                            cabinet_dict['status'] = '预警'
                    # is_warning == 2 时不做处理，因为默认状态就是“正常”

            # 将所有柜子的信息添加到返回数据中
            data1 = list(cabinet_dict_map.values())

        # 假设 ret_res 是一个自定义的响应函数，用于返回标准的响应格式
        return ret_res(code=0, data=data1)




# 三天内的报警记录
class ThreedaysWarnHistoryTableView(GenericAPIView):
    # 设置默认的查询集，获取所有的 Warn 对象
    queryset = Warn.objects.all()
    # 设置权限类（目前为空，表示不进行权限检查）
    permission_classes = []
    # 设置过滤器（目前为空，表示不应用任何过滤逻辑）
    filter_backends = []

    def get(self, request, *args, **kwargs):
        # 如果有配置过滤器，则对查询集进行过滤（当前未配置过滤器）
        queryset = self.filter_queryset(self.get_queryset())

        # 计算三天前的时间
        three_days_ago = datetime.now() - timedelta(days=3)
        # 筛选创建时间在三天内的记录
        queryset = queryset.filter(create_datetime__gte=three_days_ago)

        # 从请求参数中获取分页参数（页码和每页条数）
        page = request.query_params.get('page')
        limit = request.query_params.get('limit')

        # 调用辅助函数，根据查询集、分页参数获取预警和报警数据
        data = get_warn(queryset, page, limit)
        # 返回处理后的结果，code=0 表示成功
        return ret_res(code=0, data=data)


def get_warn(queryset, page, limit):
    if not page:
        page = str(1)
    if not limit:
        limit = str(8)
    page = int(page)
    limit = int(limit)

    # 获取所有筛选后的记录
    warns = queryset.all()
    # 对记录进行分页和排序
    warn = queryset.order_by('is_handel')[(page - 1) * limit: page * limit]

    # 构建返回的数据列表
    point_data = [
        {
            'id': each.id,
            'dept': each.point.cabinet.dept.name,
            'cabinet': each.point.cabinet.name,
            'point': each.point.name,
            'value': each.value,
            'is_handel': each.is_handel,
            'time': datetime.strftime(each.create_datetime, '%Y-%m-%d %H:%M:%S'),
            'type': '预警' if each.type == 0 else '报警'
        }
        for each in warn
    ]

    # 构建最终返回的数据结构
    data = {'total': len(warns), 'point_data': point_data}
    return data

# 返回报警数据列表
class NewWarnHistoryLineView(GenericAPIView):
    # 定义查询集，获取所有 Warn 对象
    queryset = Warn.objects.all()
    # 设置权限类（目前为空，不进行权限检查）
    permission_classes = []
    # 设置过滤器（目前为空，不应用过滤逻辑）
    filter_backends = []

    def get(self, request, *args, **kwargs):
        # 如果有配置过滤器，则对查询集进行过滤（当前未配置过滤器）
        queryset = self.filter_queryset(self.get_queryset())

        # 从请求参数中获取开始时间、结束时间、点编码和报警类型
        start = request.query_params.get('startTime')  # 开始时间
        end = request.query_params.get('endTime')  # 结束时间
        point_code = request.query_params.get('pointCode')  # 点编码

        # 如果未提供开始时间或结束时间，默认使用当天的时间范围
        if not start or not end:
            time = datetime.now()  # 当前时间
            # 设置开始时间为当天零点
            start = datetime(year=time.year, month=time.month, day=time.day, hour=0, minute=0, second=0)
            # 设置结束时间为当前时间
            end = time
        else:
            # 如果提供了时间范围，将字符串转换为 datetime 对象
            # 开始时间从提供日期的零点开始
            start = datetime.strptime(start + ' 00:00:00', '%Y-%m-%d %H:%M:%S')
            # 结束时间到提供日期的 23:59:59
            end = datetime.strptime(end + ' 23:59:59', '%Y-%m-%d %H:%M:%S')

        # 筛选报警数据
        warns = queryset.filter(
            create_datetime__gte=start  # 创建时间大于等于开始时间
        ).filter(
            create_datetime__lte=end  # 创建时间小于等于结束时间
        ).filter(
            point__code=point_code  # 点编码匹配
        ).all()

        # 准备返回数据
        data = dict()
        time_list = []  # 时间列表
        value_list = []  # 值列表

        # 遍历筛选出的报警记录，分别提取时间和值
        for each in warns:
            # 将时间转换为字符串并添加到时间列表中
            time_list.append(datetime.strftime(each.create_datetime, '%Y-%m-%d %H:%M:%S'))
            # 添加值到值列表中
            value_list.append(each.value)

        # 将时间列表和值列表组装成返回数据
        data['time_list'] = time_list
        data['value_list'] = value_list

        # 返回处理后的结果，code=0 表示成功
        return ret_res(code=0, data=data)


# 前端柜子id过来后 给该柜子下全部的点位信息
class CabinetPointNewView(GenericAPIView):
    queryset = Point.objects.all()
    serializer_class = PointSerializer
    # permission_classes = [IsAuthenticated]
    permission_classes = []

    def get(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        cabinet_id = request.query_params.get('cabinetId')
        if not cabinet_id:
            cabinet_id = Cabinet.objects.first().id
        instance = queryset.filter(cabinet__id=cabinet_id)
        serializer = self.get_serializer(instance, many=True)
        return ret_res(data=serializer.data)